
public class BitOpTester {

	public static void main(String[] args) {

		int offset = 750;

		final int SET_DO_NOT_FRAGMENT = 0x4000;
		final int SET_MORE_BITS = 0x2000;

		int value = offset | SET_DO_NOT_FRAGMENT;

		//		System.out.println("Offset: " + Integer.toBinaryString(offset));
		//		
		//		System.out.println("Value:  " + Integer.toBinaryString(value));
		//		
		//		value = value | SET_MORE_BITS;
		//		
		//		System.out.println("Value:  " + Integer.toBinaryString(value));
		//		
		//		value = value ^ SET_MORE_BITS;
		//		
		//		System.out.println("Value:  " + Integer.toBinaryString(value));
		//		
		//		value = value ^ SET_DO_NOT_FRAGMENT;
		//
		//		System.out.println("Value:  " + Integer.toBinaryString(value));
		//		
		//		value = value / 2;
		//		
		//		System.out.println("Value:  " + Integer.toBinaryString(value));
		//		
		//		value = value | SET_DO_NOT_FRAGMENT;
		//		value = value | SET_MORE_BITS;
		//
		//		System.out.println("Value:  " + Integer.toBinaryString(value));

		int[] data = {0x4500, 0x0073, 0x0000, 0x4000, 0x4011 /*, 0xb861 */, 0xc0a8, 0x0001, 0xc0a8, 0x00c7};
		int[] data2 = {0x4500, 0x0073, 0x0000, 0x4000, 0x4011, 0xb861, 0xc0a8, 0x0001, 0xc0a8, 0x00c7};

		System.out.println(Integer.toHexString((calculateChecksum(data))));
		System.out.println();
		System.out.println(validateChecksum(data2, calculateChecksum(data)));
	}

	private static short calculateChecksum(int[] data) {
		final int BIT_MASK = 0xF000;
		int value = 0;

		int sum = 0;

		for (int i = 0; i < data.length; i++) {
			sum += data[i];
		}

		String s = Integer.toBinaryString(sum);

		String temp = reverseString(s);

		String s1 = temp.substring(16);
		s1 = reverseString(s1);
		int first = Integer.valueOf(s1, 2);

		String s2 = temp.substring(0, 16);
		s2 = reverseString(s2);   	
		int second = Integer.valueOf(s2, 2);

		sum = first + second;

		sum = ~sum;

		return (short)sum;
	}

	private static boolean validateChecksum(int[] data, short value) {
		int sum = 0;

		for (int i = 0; i < data.length; i++) {
			sum += data[i];
		}

		String sumString = Integer.toBinaryString(sum);
		
		sumString = reverseString(sumString);

		int carry = 0;

		if (sumString.length() > 15) {
			String s1 = sumString.substring(16);
			s1 = reverseString(s1);
			carry = Integer.valueOf(s1, 2);
		}

		int restOfSum = 0;

		if (sumString.length() > 15) {
			String s2 = sumString.substring(0, 16);
			s2 = reverseString(s2);   	
			restOfSum = Integer.valueOf(s2, 2);
		} else {
			sumString = reverseString(sumString);
			restOfSum = Integer.valueOf(sumString, 2);
		}

		sum = carry + restOfSum;

		sum = (short)~sum;

		if (sum == 0) {
			return true;
		}

		return false;
	}

	private static String reverseString(String s) {
		StringBuffer sb = new StringBuffer(s).reverse();

		return sb.toString();	
	}
}
